<?php

class Form83{
	var $_id ;
	var $html_id ;

	var $isRich = false ;
	var $isDate = false ;
	var $Tab ;
	var $ShowInfo ;
	var $Groups;
	var	$Field_Maps;

	function __construct($id){
		$id			= (int) $id;
		C::table($id);
		$this->_id	= $id;
		
		$this->init();

		$this->Field_Maps		= array();

		foreach($this->Tab['field'] as $fid =>&$field ){
			$f83	= new Field83($field);
			$this->field83($f83, $field );

			$fid	= $field['id'];
			$this->Field_Maps[$fid]	= $f83;
		}
		$this->build_tpl();
	}

	function init(){
		include( B_DIR . '/_res/form/' . $this->_id . '.php');
		$this->Tab	= &$T;

		$this->Names	= array();
		foreach($T['field'] as $val=>&$key ){
			$this->Names[$key['id']]	= $val;
		}

		$tmp			= E::$DB->one('_table_list', 'id=' . $this->_id );
		$this->ShowInfo	= @unserialize($tmp['ShowInfo']);
		if( !$this->ShowInfo ){
			$this->ShowInfo		=  array();
		}
		if( $tmp['isGroup'] ){
			$this->Groups	= E::$DB->ary('_table_group', 'tid=' . $this->_id .' ORDER BY iOrder DESC , id ASC' , 'id, name', 'id', 'name');
		}else{
			$this->Groups	= array();
		}

		$this->html_id	= 'F' . base_convert(rand(99,999), 16, 36);
	}

	function field83(&$f83,  &$field ){
		$field['need']	= @unserialize($field['need']);
		$attrs		= array();
		if(is_array( $field['need'] )){
			$f83->hide	= true;
			$tmp 	= array();
			foreach($field['need'] as $k=>$v){
				$tmp[ $this->Names[$k] ] = array_keys($v);
				//array_push($tmp,  $this->Names[$k] . ':[' . join(',', $v) . ']');
			}
			//$attrs	.=	' depends="' . join(',', $tmp) . '"';
			if( !empty( $tmp ) ){
				$attrs['ShowOn']	= $tmp;
			}
		}
		if( $field['elementType'] == 'xhr' ){
			//$attrs	.= ' depField="' . $this->Names[ $field['DepField'] ] . '"';
			$attrs['ShowBy']	= $this->Names[ $field['DepField'] ];
		}
		$f83->attrs		= $attrs;
		$f83->note		= $field['note'];

		if( $field['elementType'] == 'select' || $field['elementType'] == 'select' ){
			$field['size']	= $field['size'] ? ' style="width:' . ($field['size']  + 5) . 'ex;"' : '';
		}else{
			$field['size']	= $field['size'] ? ' size="' . $field['size'] . '" maxlength="' . $field['size'] . '"' :'';
		}

		call_user_func( array($this, 'build_' . $field['elementType']), $field, $f83);
	}

	function build_checkbox(&$field , &$f83){
		$f83->vals	= '{-foreach from=$L.' . $field['fieldKey'] . ' item=a-}{-$a-},{-/foreach-}';

		$tmp	= "";
		foreach($field['child'] as $val=>&$var){
			$tmp .= '<label for="' . $this->html_id . '_' . $field['id'] . '_' . $val . '"><input type="checkbox" id="' . $this->html_id . '_' . $field['id'] . '_' . $val . '" name="' . $field['fieldKey'] . '[]" value="' . $val . '"/>' . $var . '</label>';
		}

		$f83->element	= $tmp;

		if( empty($field['alert']) ){
			$field['alert']	= '至少要选择一个' . $field['fieldName'] . '选项!';
		}
		if ( $field['isForce'] ){
			$f83->js		=	$this->addCheckedValidate($field);
		}
	}

	function build_file(&$field, &$f83){
		
		$f83->element = '<input type="file" name="' . $field['fieldKey'] . '"' . $size . ' /> ' . ' {-if $L.' . $field['fieldKey'] . '-}<a target="_blank" href="{-$L.' . $field['fieldKey'] . '-}">察看</a> <a class="note">再次上传覆盖旧的</a>{-/if-}';

		$xxx	= $field['regs'] ? ' !e.value.match(/' . $field['regs'] . '/i)':' e.value =="" ';

		if( $field['isForce'] || $field['regs'] ){
			$f83->js	= '
				var e = elements["' . $field['fieldKey'] . '"];
				if( ' . $xxx . ' ){
					alert("' . $field['fieldName'] . ' 验证提示:\n  ' . $field['alert'] . '");
					e.select(); e.focus(); return true;
				}';
		}
	}

	function build_password(&$field ,&$f83){
		$f83->element = '<input type="password" name="' . $field['fieldKey'] . '" value="{-$L.' . $field['fieldKey'] . '-}"' . $field['size'] . ' /> ';
	}

	function build_radio(&$field ,&$f83){
		$tmp	= "";
		foreach($field['child'] as $val=>&$var){
			$tmp .= '<label for="' . $this->html_id . '_' . $field['id'] . '_' . $val . '"><input type="radio"   id="' . $this->html_id . '_' . $field['id'] . '_' . $val . '" name="' . $field['fieldKey'] . '" value="' . $val . '"{-if "' . $val . '"==$L.' . $field['fieldKey'] . '-} checked="checked"{-/if-} />' . $var . '</label>';
		}
		$f83->element	= $tmp;
		if( empty($field['alert']) ){
			$field['alert']	= '您必须择' . $field['fieldName'] . '选项';
		}
		if ( $field['isForce'] ){
			$f83->js		=	$this->addCheckedValidate($field);
		}
	}


	function build_richtext(&$field ,&$f83){
		$id	= $this->html_id . 'r' . $field['id'];
		$tmp	= '<textarea  name="'.$field['fieldKey'].'" id="r'.$id.'" class="oEditor2">{-$L.'.$field['fieldKey'].'|escape-}</textarea>';
		$tmp	.= '<script type="text/javascript">AddEditor("oEdit' . $id . '", "r' . $id . '", '. $this->_id .',{-$L.id|default:0-},{-php-}$t = time(); echo $t . ",\'" . md5( \''. $this->_id.'\'.( (int) $this->_tpl_vars[\'L\'][\'id\']) .$this->_tpl_vars[\'html\'][\'whisper\'] .$t ) {-/php-}\');</script>';
		$f83->element	= $tmp;
		$this->isRich	= true;
	}

	function build_select(&$field ,&$f83){
		$tmp = '<select name="' . $field['fieldKey']  . '"' . $field['size'] . '>';
		foreach($field['child'] as $val => &$var ){
			$tmp .= '<option value="' . $val . '"{-if "' . $val . '"==$L.' . $field['fieldKey'] . '-} selected="selected" class="selected"{-/if-}>' . $var . '</option>';
		}
		$tmp .= '</select>';
		$f83->element	= $tmp;
	}

	function build_text(&$field ,&$f83){
		$f83->element	= '<input type="text" name="' . $field['fieldKey'] . '" value="{-$L.' . $field['fieldKey'] . '|escape-}"' . $field['size'] . '/> ';

		$xxx	= $field['regs'] ? ' !e.value.match(/' . $field['regs'] . '/)':' e.value =="" ';
		$pat = array();
		if( preg_match('/mail/i', $field['fieldKey']) ){
			$pat[]	= '!e.value.match(/^[\w\_\.\-]{2,22}\@([\w\-]{2,30}\.){1,4}[a-z]{2,5}$|^$/i)';
			if( empty($field['alert']) ){
				$field['alert'] = '请输入正确的Emal地址!';
			}
		}else{
			if($field['regs']){
				$pat[]	= ' !e.value.match(/' . $field['regs'] . '/i)';
			}
		}
		if( $field['isForce'] ){
			$pat[]	= 'e.value.match(/^\s*$/)';
		}
		if( count($pat) ){
			$pat		= join(' || ', $pat);
			$msg		= $field['alert'] ? $field['alert'] : '请输入' . $field['fieldName'] . '!';
			$f83->js	= '
				var e = elements["' . $field['fieldKey'] . '"];
				if( '.$pat.' ){
					alert("' . $msg . '"); e.select();e.focus(); return true;
				}';
		}
	}

	function build_textarea(&$field ,&$f83){
		$f83->element	= '<textarea name="' . $field['fieldKey'] . '" style="width:99%;height:180px;">{-$L.' . $field['fieldKey'] . '|escape-}</textarea>';
		$xxx	= $field['regs'] ? ' !e.value.match(/' . $field['regs'] . '/)' : ' e.value =="" ';
		if( $field['isForce'] || $field['regs'] ){
			$f83->js	= '
				var e = elements["'.$field['fieldKey'].'"];
				if( ' . $xxx . ' ){
					alert("' . $field['fieldName'] . ' 验证提示:\n  ' . $field['alert'] . '"); e.select(); e.focus();return true;
				}';
		}
	}


	function build_xhr(&$field ,&$f83){
		$f83->element	= '<select name="' . $field['fieldKey'] . '" val="{-$L.' . $field['fieldKey'] . '-}"' . $field['size'] . '></select>';
	}

	function build_date(&$field ,&$f83){
		$f83->element	= '<input type="text" class="scheduler" value="{-if $L.'.$field['fieldKey'].'-}{-$L.'.$field['fieldKey'].'|date_format:"%Y-%m-%d"-}{-/if-}" name="' . $field['fieldKey'] . '" />';
		$this->isDate	= true;
		if( $field['isForce'] ){
			$pat	= '^\d{2,4}\-\d{1,2}\-\d{1,2}$';
		}else{
			$pat	= '^\d{2,4}\-\d{1,2}\-\d{1,2}$|^$';
		}
		$f83->js		= '
			var e = elements["'.$field['fieldKey'].'"];
			if(  !e.value.match(/' . $pat . '/)){
				alert("错误信息:\\n  日期格式错误 ！  "); e.select();  e.focus();  return true;
			}';
	}
	
	function build_color(&$field ,&$f83){
		$f83->element	= '<input type="text" class="MooColor" value="{-$L.'.$field['fieldKey'].'-}" name="' . $field['fieldKey'] . '" />';
		$this->isDate	= true;
		if( $field['isForce'] ){
			$pat	= '^\#[0-9a-f]{6}$';
		}else{
			$pat	= '^\#[0-9a-f]{6}$|^$';
		}
		$f83->js		= '
			var e = elements["'.$field['fieldKey'].'"];
			if(  !e.value.match(/' . $pat . '/)){
				alert("错误信息:\\n  颜色格式错误 ！  "); e.select();  e.focus();  return true;
			}';
	}
	
	function addCheckedValidate(&$field){
		$name		=  ( $field['elementType'] == 'checkbox' ) ? $field['fieldKey'].'[]' : $field['fieldKey'];
		$js	= '
			var o = elements["' . $name . '"];
			if(!Array.some(o, function(o){
				return o.checked;
			})){
				alert("' . $field['fieldName'] . ' 验证提示:\n  ' . $field['alert'] . '");
				o.item(0).focus(); return true;
			}';
		return $js;
	}

	function build_tpl(){

		$Groups_Fields	= array();
		$last_in	= 0;
		$last_col	= 0;
		$max_col	= 0;
		foreach($this->Field_Maps as $fid => &$f83 ){
			$gid	= $f83->gid;
			if( !is_array( $Groups_Fields[$gid] ) ){
				$Groups_Fields[$gid]	= array();
			}
			if( $this->ShowInfo[$fid] ){
				if( !$last_in || !$this->Field_Maps[$last_in] ){
					die('Error on ' . __FILE__ . ' ' . __LINE__);
				}
				$si	=& $this->ShowInfo[$fid];
				if( $si[0] == 'in' ){
					$f83->isIn	= true;
					array_push($this->Field_Maps[$last_in]->embeds , $fid);
				}else if( $si[0] == 'col' ){
					$f83->isCol	= true;
					$last_in = $fid ;
					$this->Field_Maps[$last_col]->isCol	= true;
					$this->Field_Maps[$last_col]->isFol	= true;
					array_push($this->Field_Maps[$last_col]->rights , $fid);

					$_max_col	= count( $this->Field_Maps[$last_col]->rights ) + 1;
					if( $_max_col > $max_col){
						$max_col	= $_max_col;
					}
				}else if( $si[0] == 'row' ){
					$f83->isCol	= true;
					$f83->isRow	= true;
					$this->Field_Maps[$last_col]->isCol	= true;
					$this->Field_Maps[$last_col]->isFol	= true;
					array_push($this->Field_Maps[$last_col]->rights , $fid);
					$last_in = $last_col = 0 ;
				}else{
					die('Error on ' . __FILE__ . ' ' . __LINE__);
				}
			}else{
				$last_col	= $last_in = $fid;
				array_push( $Groups_Fields[$gid] , $fid);
			}
		}

		foreach($this->Field_Maps as &$f83 ){
			if( $f83->isFol ){
				$f83->col_count	= ( count( $f83->rights ) + 1 );
				foreach( $f83->rights as $_fid){
					$this->Field_Maps[$_fid]	->col_count	= $f83->col_count;
				}
			}else{
				if( !$f83->isCol && !$f83->isIn ){
					$f83->col_count	= 1;
					if( !empty( $f83->rights  ) ){
						die('Error on ' . __FILE__ . ' ' . __LINE__);
					}
				}
			}

		}
		
		$shtml	= "<tbody id=\"" . $this->html_id . "\">";
	
		if( $this->isRich ){
			$shtml	= '<script type="text/javascript" src="{-$smarty.const.W_DIR-}/_admin/src/js/editor.js"></script>' . $shtml;
		}
		if( $this->isDate ){
			$shtml	= '<script type="text/javascript" src="{-$smarty.const.W_DIR-}/_admin/src/js/scheduler.js"></script>' . $shtml;
			$shtml	= '<link rel="stylesheet" media="all" rev="stylesheet" href="{-$smarty.const.W_DIR-}/_admin/src/img/_scheduler.css" />' . $shtml;

		}
		foreach( $Groups_Fields as $gid => &$glist){
			$shtml	.= "<tbody id=\"" .$this->html_id . "_" . $gid . "\">";

			if( $gid ){
				$shtml	.= "<tr class=\"fieldTitle\"><td ".( $max_col > 1 ? ' colspan="4"' : 'colspan="2"' )."><div class=\"fieldTitle2\">" .$this->Groups[$gid] . "</div></td></tr>";
			}

			foreach($glist as $fid){
				$f83	=& $this->Field_Maps[$fid];
				$col		= $max_col - $f83->col_count;
				if( $col > 1 ){
					$colspan	= ' colspan="3"';
				}else{
					$colspan	= '';
					// ' width="37%"';
				}

				if( $f83->hide ){
					$shtml	.= '<tr class="f83e" style="display:none">';
				}else{
					$shtml	.= '<tr class="f83e">';
				}
					$shtml	.= '<td class="fieldName">' . $f83->name  . '</td>';

					$shtml	.= "<td{$colspan} class=\"fieldValue\">" . $f83->body() ;
						foreach($f83->embeds as $_fid){
							$_f83	=& $this->Field_Maps[$_fid];
							if( $_f83->hide ){
								$shtml	.= ' &nbsp;&nbsp;  <span class="f83e" style="display:none">' . $_f83->body(). '</span>';
							}else{
								$shtml	.= ' &nbsp;&nbsp;  <span class="f83e">' . $_f83->body(). '</span>';
							}
						}
						unset($_f83);
					$shtml	.= "</td>";

					foreach($f83->rights as $_fid){
						$_f83	=& $this->Field_Maps[$_fid];
						$shtml	.= '<td class="fieldName fieldName2">' . $_f83->name  . '</td>';
						$shtml	.= "<td class=\"fieldValue\">" . $_f83->body() ;
						foreach($_f83->embeds as $__fid){
							$__f83	=& $this->Field_Maps[$__fid];
							if( $__f83->hide ){
								$shtml	.= ' &nbsp;&nbsp;  <span class="f83e" style="display:none">' . $__f83->body(). '</span>';
							}else{
								$shtml	.= ' &nbsp;&nbsp;  <span class="f83e">' . $__f83->body(). '</span>';
							}
						}
						unset($__f83);
					$shtml	.= '</td>';

					}
				$shtml	.= "</tr>\n\n";
			}
			$shtml	.= "</tbody>\n";
		}
		unset($f83);
		$shtml	.= "</tbody>\n";
		$vals	= "\tvar Vals = {};\n";
			foreach($this->Field_Maps as $fid => &$f83){
				if( $f83->vals ){
					$vals	.= "\tVals[\"" . $f83->key . "\"] = \"". $f83->vals . "\";\n";
				}
			}
		$attrs	= array();
		$shtml	.= "<script type=\"text/javascript\">\n(function(){ \n" . $vals . " \n\tnew Form83('".$this->html_id . "', function(){\n";
			$shtml	.= "\t\tvar elements = this.dom.elements;\n";
			foreach($this->Field_Maps as $fid => &$f83){
				$js	= trim( $f83->js );
				if( !empty($js) ){
					$shtml	.= "\t\ttry{\n\t\t\t" . $js . "\n\t\t}catch(err){ alert(err) ;return true;}\n";
				}
				if( $f83->attrs ){
					$attrs[$f83->key] = $f83->attrs;
				}
			}
		$shtml	.= "\n\t}, " . json_encode( $attrs ) . " , Vals); \n })();\n";
		$shtml	.= "</script>\n";
		file_put_contents( B_DIR . '/_res/form/' . $this->_id . '.tpl' , $shtml);
	}
}

class Field83{
	var $id;
	var $gid;
	var $attrs;
	var $key;
	var $name;
	var $element;
	var $vals;

	var $note;
	var $hide;
	var $js;

	var $embeds = array();
	var $rights = array();

	var $isIn	= false ;
	var $isCol	= false ;
	var $isFol	= false ;
	var $isRow	= false ;

	var $col_count ;

	function __construct($field){
		if( !is_array($field) ){
			die('Error on ' . __FILE__ . ' ' . __LINE__);
		}
		$this->id		= $field['id'];
		$this->gid		= $field['gid'];
		$this->key		= $field['fieldKey'];
		$this->name		= $field['fieldName'];
	}

	function getNote(){
		if( $this->note ){
			return " <span class=\"note\">" . $this->note . "</span>";
		}
		return "";
	}

	function body(){
		return   $this->element . $this->getNote() ;
	}
}

?>
